package com.CmJava.service.imp;

import com.CmJava.entity.*;
import com.CmJava.entity.comment.CommentMysql;
import com.CmJava.entity.project.*;
import com.CmJava.mapper.ProjectCommentMapper;
import com.CmJava.mapper.ProjectDisplayMapper;
import com.CmJava.mapper.TechFilterMapper;
import com.CmJava.service.ProjectService;
import com.CmJava.utils.BackupUtil;
import com.CmJava.utils.OldProjectParseUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service
public class ProjectServiceImpl implements ProjectService {

    @Autowired
    private TechFilterMapper techFilterMapper;

    @Autowired
    private ProjectDisplayMapper projectDisplayMapper;

    @Autowired
    private ProjectCommentMapper projectCommentMapper;

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;


    @Override
    public ResultEntity getTechFilter() {
        Wrapper<TechFilter> techFilterQueryWrapper = new QueryWrapper<>();
        ((QueryWrapper<TechFilter>) techFilterQueryWrapper).select("id","techName");
        List<TechFilter> techFilters = techFilterMapper.selectList(techFilterQueryWrapper);
        if (techFilters.size()==0 || techFilters==null){
            return ResultEntity.failureWithoutMessage();
        }
        return ResultEntity.successWithMessage(techFilters);
    }

    @Override
    public ResultEntity getProjectDisplay() {
        Wrapper<ProjectDisplay> projectDisplayQueryWrapper = new QueryWrapper<>();
        ((QueryWrapper<ProjectDisplay>) projectDisplayQueryWrapper).select("id","projectName","projectDescription","techId");

        List<ProjectDisplay> projectDisplays = projectDisplayMapper.selectList(projectDisplayQueryWrapper);
        if (projectDisplays.size()==0 || projectDisplays==null){
            return ResultEntity.failureWithoutMessage();
        }

        // 封装好每个项目使用的技术选型
        for (ProjectDisplay projectDisplay : projectDisplays) {
            parseTech(projectDisplay);
        }
        return ResultEntity.successWithMessage(projectDisplays);
    }

    @Override
    public ResultEntity getProjectMysql(String projectId) {
        ProjectDisplay projectDisplay = projectDisplayMapper.selectById(projectId);
        if (projectDisplay!=null){
            //映射下技术选型
            parseTech(projectDisplay);
            return ResultEntity.successWithMessage(projectDisplay);
        }

        return ResultEntity.failureWithoutMessage();
    }

    //映射技术选型
    public void parseTech(ProjectDisplay projectDisplay){
        String[] techIds = projectDisplay.getTechId().split(",");
        ArrayList<String> techNames = new ArrayList<>();
        for (String techId : techIds) {
            TechFilter techFilter = techFilterMapper.selectById(techId);
            if(techFilter!=null) {
                techNames.add(techFilter.getTechName());
            }
        }
        projectDisplay.setTechName(techNames);
    }

    @Override
    public ResultEntity getRedisProject(String key) {
        ResultEntity resultEntity = dispatchProject(key);
        return resultEntity;
    }

    //分发新旧项目以适应新系统
    private ResultEntity dispatchProject(String key) {
        Integer projectId = Integer.parseInt(key.split("_")[0].substring(7));
        if (projectId > 12) {
            ResultEntity resultEntity = getNewProject(key);
            return resultEntity;
        } else {
            ResultEntity resultEntity = getOldProject(key);
            return resultEntity;
        }
    }

    private ResultEntity getOldProject(String key) {
        if (redisTemplate.hasKey(key)) {
            Project project = null;
            String projectRedisData = "";
            try {
                project = (Project) redisTemplate.opsForValue().get(key);
                projectRedisData = OldProjectParseUtil.parseOldProject(project);
            } catch (ClassCastException e) {
                //转换失败说明已经被转成新博客的格式了
                return getNewProject(key);
            }

            //转换完毕存回去
            redisTemplate.opsForValue().set(key, projectRedisData);

            return ResultEntity.successWithMessage(projectRedisData);
        } else {
            return ResultEntity.failureWithoutMessage();
        }
    }

    private ResultEntity getNewProject(String key) {
        if (redisTemplate.hasKey(key)) {
            String projectRedisData = (String) redisTemplate.opsForValue().get(key);
            return ResultEntity.successWithMessage(projectRedisData);
        } else {
            return ResultEntity.failureWithoutMessage();
        }
    }

    @Override
    public ResultEntity getNewProjectId() {
        Wrapper<ProjectDisplay> projectDisplayQueryWrapper = new QueryWrapper<>();
        ((QueryWrapper<ProjectDisplay>) projectDisplayQueryWrapper).select("*");
        Integer num = projectDisplayMapper.selectCount(projectDisplayQueryWrapper);
        if (num==null || num<0){
            return ResultEntity.failureWithoutMessage();
        }
        return ResultEntity.successWithMessage(num+1);
    }

    @Override
    public ResultEntity addProjectRedis(String key,String projectRedisData) {
        redisTemplate.opsForValue().set(key,projectRedisData);
        return ResultEntity.successWithoutMessage();
    }

    @Override
    public ResultEntity addImgs(String title, MultipartFile fileImage) throws IOException {
        String os = System.getProperty("os.name");
        File imagePath;  //图片存放地址

        if (os.toLowerCase().startsWith("win")) {  //windows系统
            String path = System.getProperty("user.dir");  //获取项目相对路径
            imagePath = new File(path+"/src//main/resources/static/my_images");
        }else{//linux系统
            //获取根目录
            //如果是在本地windows测试环境下，目录为项目的target\classes下
            //如果是linux环境下，目录为jar包同级目录
            File rootPath = new File(ResourceUtils.getURL("classpath:").getPath());
            if(!rootPath.exists()){
                rootPath = new File("");
            }

            imagePath = new File(rootPath.getAbsolutePath()+"/assets/Project_Imgs");
        }

        if(!imagePath.exists()){
            //不存在，创建
            imagePath.mkdirs();
        }
        //获取文件名称
        String imageName = fileImage.getOriginalFilename();

        //创建图片存放地址
        File imageResultPath = new File(imagePath+"/"+imageName);
        if(imageResultPath.exists()){
            return ResultEntity.failureWithoutMessage();
        }


        fileImage.transferTo(imageResultPath);

        System.out.println("imageResultPath:"+imageResultPath.getCanonicalPath());
        return ResultEntity.successWithoutMessage();
    }

    @Override
    public ResultEntity getModelAndChildNum(String key) {

        if (redisTemplate.hasKey(key)) {

            Project project = (Project) redisTemplate.opsForValue().get(key);



            ArrayList<Integer> list = new ArrayList<>();
            List<ProjectModel> model = project.getModel();

            list.add(model.size());
            for (ProjectModel projectModel : model) {
                list.add(projectModel.getChildModel().size());
            }
            return ResultEntity.successWithMessage(list);
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity getThisProject(String key) {
        if (redisTemplate.hasKey(key)) {
            Project project = (Project) redisTemplate.opsForValue().get(key);
            return ResultEntity.successWithMessage(project);
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity updateThisModle(String key, String modelId, ProjectModel projectModel) {
        if (redisTemplate.hasKey(key)) {

            Project project = (Project) redisTemplate.opsForValue().get(key);
            project.getModel().set(Integer.parseInt(modelId)-1,projectModel);

            redisTemplate.opsForValue().set(key,project);
            return ResultEntity.successWithMessage(project);
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity getThisProjectTech(String projectId) {
        ProjectDisplay projectDisplay = projectDisplayMapper.selectById(projectId);
        if (projectDisplay!=null){
            QueryWrapper<TechFilter> techFilterQueryWrapper = new QueryWrapper<>();
            String[] techIds = projectDisplay.getTechId().split(",");

            techFilterQueryWrapper.select("*");
            List<TechFilter> techFiltersAll = techFilterMapper.selectList(techFilterQueryWrapper);

            ArrayList<List> result = new ArrayList<>();
            result.add(techFiltersAll);
            result.add(Arrays.asList(techIds));

            return ResultEntity.successWithMessage(result);
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity updateProjectMysql(ProjectDisplay projectDisplay) {
        int i = projectDisplayMapper.updateById(projectDisplay);
        if (i!=1){
            return ResultEntity.failureWithoutMessage();
        }

        return ResultEntity.successWithoutMessage();
    }

    @Override
    public ResultEntity updateTech(String key, String front, String back) {
        if (redisTemplate.hasKey(key)) {

            Project project = (Project) redisTemplate.opsForValue().get(key);
            project.setFrontTech(front);
            project.setBackTech(back);
            redisTemplate.opsForValue().set(key,project);
            return ResultEntity.successWithoutMessage();
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity addProjectMysql(ProjectDisplay projectDisplay) {
        String today = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        projectDisplay.setCreateTime(today);

        ProjectDisplay display = projectDisplayMapper.selectById(projectDisplay.getId());
        int num=-1;
        if (display==null){
            num = projectDisplayMapper.insert(projectDisplay);
        }else {
            num = projectDisplayMapper.updateById(projectDisplay);
        }
        if (num!=-1){
            return ResultEntity.successWithoutMessage();
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity addProjectCommentMysql(String projectId) {
        Integer integer = projectCommentMapper.selectCount(null);
        int insert = projectCommentMapper.insert(new CommentMysql(integer + 1, Integer.parseInt(projectId), 0, "--"));
        if (insert!=-1){
            return ResultEntity.successWithoutMessage();
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity getProjectList() {
        QueryWrapper<ProjectDisplay> projectDisplayQueryWrapper = new QueryWrapper<>();
        projectDisplayQueryWrapper.select("id","projectName");

        List<ProjectDisplay> projectDisplays = projectDisplayMapper.selectList(projectDisplayQueryWrapper);

        return ResultEntity.successWithMessage(projectDisplays);
    }

    @Override
    public void deleteAllImg(String projectId) {
        String key ="project"+projectId+"_for_MyWeb";
        if (redisTemplate.hasKey(key)) {
            Project project = (Project) redisTemplate.opsForValue().get(key);

            for (ProjectModel projectModel : project.getModel()) {
                for (ChildModel childModel : projectModel.getChildModel()) {
                    childModel.setChildModelImg("--");
                }
            }

            redisTemplate.opsForValue().set(key,project);
        }
    }

    @Override
    public ResultEntity deleteProjectChildModel(String projectId, int modelIndex, int childIndex) {
        String key ="project"+projectId+"_for_MyWeb";
        if (redisTemplate.hasKey(key)) {
            Project project = (Project) redisTemplate.opsForValue().get(key);

            project.getModel().get(modelIndex).getChildModel().remove(childIndex);

            redisTemplate.opsForValue().set(key,project);

            return  ResultEntity.successWithoutMessage();
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity deleteProjectModel(String projectId, int modelIndex) {
        String key ="project"+projectId+"_for_MyWeb";
        if (redisTemplate.hasKey(key)) {
            Project project = (Project) redisTemplate.opsForValue().get(key);

            project.getModel().remove(modelIndex);

            redisTemplate.opsForValue().set(key,project);

            return  ResultEntity.successWithoutMessage();
        }
        return ResultEntity.failureWithoutMessage();
    }

    @Override
    public ResultEntity getProjectImg(String projectId) {
        QueryWrapper<ProjectDisplay> projectDisplayQueryWrapper = new QueryWrapper<>();
        projectDisplayQueryWrapper.eq("id",projectId);
        projectDisplayQueryWrapper.select("imgName");
        String  projectImg = projectDisplayMapper.selectList(projectDisplayQueryWrapper).get(0).getImgName();
        return ResultEntity.successWithMessage(projectImg);
    }

    @Override
    public ResultEntity backupProject(String projectId) {
        String key = "project" + projectId + "_for_MyWeb";

        //备份redis
        ResultEntity resultEntity = dispatchProject(key);
        if (resultEntity.getResultFlag()) {
            return BackupUtil.backupTheProject(key, resultEntity.getData());
        }
        return ResultEntity.failureWithMessage("备份项目(" + key + ")失败，数据库内未找到该篇项目");
    }

    @Override
    public ResultEntity<Object> downBackupProject() {
        return BackupUtil.downBackupProject();
    }

    //    @Override
//    public ResultEntity addProjectFrontBack(String key, Project project) {
//        if (redisTemplate.hasKey(key)) {
//            Project project0 = (Project) redisTemplate.opsForValue().get(key);
//            project0.setTechClass(project.getTechClass());
//            redisTemplate.opsForValue().set(key,project0);
//        }else {
//            redisTemplate.opsForValue().set(key,project);
//        }
//        return ResultEntity.successWithoutMessage();
//    }
//
//    @Override
//    public ResultEntity addChildModel(String key, String modelName, String childModelName, String childModelDesc) {
//        HashMap<String, List<String>> hashMap = new HashMap<>();
//        ArrayList<String> arrayList = new ArrayList<>();
//        arrayList.add(childModelDesc);
//        hashMap.put(childModelName,arrayList);
//        ProjectModel projectModel = new ProjectModel();
////        ProjectModel projectModel = new ProjectModel(modelName, hashMap);
//
//
//        if (redisTemplate.hasKey(key)) {
//            Project project0 = (Project) redisTemplate.opsForValue().get(key);
//
//            List<ProjectModel> model = project0.getModel();
//
//            if (model!=null){
//                model.add(projectModel);
//                System.out.println(111);
//
//            }else if (model==null ){
//                System.out.println(55656566);
//                ArrayList<ProjectModel> projectModels = new ArrayList<>();
//                projectModels.add(projectModel);
//                project0.setModel(projectModels);
//                System.out.println(222);
//            }
//            System.out.println(project0);
//            redisTemplate.opsForValue().set(key,project0);
//        }else {
//            return ResultEntity.failureWithoutMessage();
//        }
//        return ResultEntity.successWithoutMessage();
//    }
}
